﻿#include "powercalculator.h"
#include <QLabel>
#include <QTableWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QString>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QSize>
#include <QIcon>
#include <QDesktopWidget>
#include <QApplication>
#include <QDebug>
#include <QHeaderView>
#include <QTime>
#include <QTimeEdit>
#include <QDateTime>
PowerWindow::PowerWindow(QWidget* parent):QWidget(parent)
{
    setFixedSize(530,300);
//    setFixedSize(minimumSize());
    QDesktopWidget *desktop=QApplication::desktop();
    move((desktop->width()-width())/2,(desktop->height()-height())/2);
    this->setWindowFlags(Qt::WindowStaysOnTopHint);
    setWindowTitle(tr("Dispatching Power Calculator"));
    QLabel*label1=new QLabel(tr("Dispatching orders"),this);
    label1->setAlignment(Qt::AlignHCenter);
    QLabel*label2=new QLabel(tr("Dispatching power"),this);
    label2->setAlignment(Qt::AlignHCenter);
    tableView=new QTableView(this);
    tableModel=new QStandardItemModel(this);
    tableModelInit();
    tableDelegate=new TableDelegate(tableView);
    tableView->setModel(tableModel);
    tableView->setItemDelegate(tableDelegate);
    textEdit=new QTextEdit(this);
    textEdit->setReadOnly(true);
    textEdit->setMinimumWidth(240);
    datetimeLCD=new QLCDNumber(19,this);
    datetimeLCD->setSegmentStyle(QLCDNumber::Flat);
    datetimeLCD->setFrameStyle(QFrame::Plain);
    datetimeLCD->setStyleSheet("QLCDNumber{background-color:rgb(255,255,255);color:#CD1076;}");
    timer=new QTimer(this);
    timer->start(1000);
    buttonAdd=new QPushButton(tr("Add"),this);
    buttonAdd->setGeometry(249,250,70,25);
    buttonAdd->setToolTip(tr("click to add a dispatch"));
    buttonCal=new QPushButton(tr("Calculate"),this);
    buttonCal->setToolTip(tr("click to calculate power"));
    buttonClr=new QPushButton(tr("Clear"),this);
    buttonClr->setToolTip(tr("click to clear all dispatchs"));
    labelAbout=new ClickableLabel(tr("about..."),this);
    vbox1=new QVBoxLayout;
    vbox2=new QVBoxLayout;
    hbox1=new QHBoxLayout;
    hbox3=new QHBoxLayout;
    vbox3=new QVBoxLayout;
    vbox1->addWidget(label1);
    vbox1->addWidget(tableView);
    vbox2->addWidget(label2);
    vbox2->addWidget(textEdit);
    hbox1->addWidget(datetimeLCD);
    hbox1->addStretch();
    hbox1->addWidget(buttonAdd);
    hbox1->addWidget(buttonCal);
    hbox1->addWidget(buttonClr);
    hbox1->addSpacing(10);
    hbox1->addWidget(labelAbout);
    hbox3->addLayout(vbox1);
    hbox3->addSpacing(10);
    hbox3->addLayout(vbox2);
    vbox3->addLayout(hbox3);
    vbox3->addLayout(hbox1);
    setLayout(vbox3);
    connect(buttonAdd,&QPushButton::clicked,this,&PowerWindow::addOneRow);
    connect(buttonClr,&QPushButton::clicked,this,&PowerWindow::clearAll);
    connect(buttonCal,&QPushButton::clicked,this,&PowerWindow::calPower);
    connect(labelAbout,&ClickableLabel::clicked,this,&PowerWindow::about);
    connect(timer,&QTimer::timeout,this,&PowerWindow::setDatatime);
}
void PowerWindow::tableModelInit(){
    tableModel->setColumnCount(2);
    tableModel->setRowCount(1);
    tableModel->setHeaderData(0,Qt::Horizontal,tr("Time"));
    tableModel->setHeaderData(1,Qt::Horizontal,tr("Load(MW)"));
    tableModel->setData(tableModel->index(0,0),QTime(0,0));
    tableModel->setData(tableModel->index(0,1),0,Qt::EditRole);
    tableModel->setData(tableModel->index(0,1),tr("double click to input"),Qt::DisplayRole);
}

void PowerWindow::addOneRow(){
    QStandardItem* timeItem=new QStandardItem;
    timeItem->setData(QTime(0,0),Qt::EditRole);
    QStandardItem* loadItem=new QStandardItem;
    loadItem->setData(0,Qt::EditRole);
    if (tableModel->rowCount()%2==1){
        timeItem->setData(QColor("#CCFFCC"),Qt::BackgroundColorRole);
        loadItem->setData(QColor("#CCFFCC"),Qt::BackgroundColorRole);
    }
   tableModel->appendRow(QList<QStandardItem*>()<<timeItem<<loadItem);
}
void PowerWindow::calPower(){
    auto rowCount=tableModel->rowCount();
    for (int i=1;i<rowCount;++i){
        auto index=tableModel->index(i,0);
        auto previousRowIndex=tableModel->index(i-1,0);
        if (tableModel->data(index,Qt::EditRole)<=tableModel->data(previousRowIndex,Qt::EditRole)){
            QMessageBox::critical(this,tr("error"),QString("%1\n%2").arg(tr("time error"),\
                                                                           tr("please input a time that is greater\nthan the previous row time.")));
            QItemSelectionModel* selectionModel=tableView->selectionModel();
            QItemSelection itemSelection(index,index);
            selectionModel->select(itemSelection,QItemSelectionModel::ClearAndSelect);
            return;
        }
    }
    QHash<QTime,double> orderHash;
    QList<QTime> order_AmLow;//放置早上谷段时间的调令,早低段(00:00-07:00)
    QList<QTime> order_AmHigh;//放置早上峰段时间的调令,早高段(07:00-11:00)
    QList<QTime> order_Normal;//放置平段时间的调令,//平段(11:00-19:00)
    QList<QTime> order_PmHigh;//放置晚上峰段时间的调令,晚高段(19:00-23:00)
    QList<QTime> order_PmLow;//放置晚上谷段时间的调令,晚低段(23:00-24:00)
    double power_AmLow=0;
    double power_AmHigh=0;
    double power_Normal=0;
    double power_PmHigh=0;
    double power_PmLow=0;
    double power_Total=0;
    for (int row=0;row<rowCount;++row){
        QTime orderTime=tableModel->data(tableModel->index(row,0),Qt::EditRole).toTime();
        if (orderTime<=QTime(7,0,0))
            order_AmLow.append(orderTime);
        if (orderTime>QTime(7,0,0)&&orderTime<=QTime(11,0,0))
            order_AmHigh.append(orderTime);
        if (orderTime>QTime(11,0,0)&&orderTime<=QTime(19,0,0))
            order_Normal.append(orderTime);
        if (orderTime>QTime(19,0,0)&&orderTime<=QTime(23,0,0))
            order_PmHigh.append(orderTime);
        if (orderTime>QTime(23,0,0)&&orderTime<QTime(24,0,0))
            order_PmLow.append(orderTime);
        double orderLoad=tableModel->data(tableModel->index(row,1),Qt::EditRole).toDouble();
        orderHash.insert(orderTime,orderLoad);
    }
/*!
 * 早低段(00:00-07:00)
 */
    double orderEnd=orderHash.value(order_AmLow.at(0));
    if (order_AmLow.count()!=1){
        double hour; //小时数
        for (int i=1;i<order_AmLow.count();++i){

            if (i==1){
                double hourDec=order_AmLow.at(1).minute()/60.0;
                hour=hourDec+order_AmLow.at(1).hour();
            }
            else{
                double hourDec=(order_AmLow.at(i).minute()+60-order_AmLow.at(i-1).minute())/60.0;
                int hInt=order_AmLow.at(i).hour()-order_AmLow.at(i-1).hour()-1;
                hour=hInt+hourDec;
            }
            power_AmLow+=hour*orderEnd;
            orderEnd=orderHash.value(order_AmLow.at(i));
            if (i==order_AmLow.count()-1){
                double hourDec=(60-order_AmLow.at(i).minute())/60.0;
                hour=7-order_AmLow.at(i).hour()-1+hourDec;
                power_AmLow+=hour*orderEnd;
            }
        }
    }
    else{
         power_AmLow+=7*orderEnd;
    }
/*!
 * 早高段(07:00-11:00)
 */
    if (order_AmHigh.count()!=0){
        double hour;
        for (int i=0;i<order_AmHigh.count();++i){

            if (i==0){
                double hourDec=order_AmHigh.at(0).minute()/60.0;
                hour=hourDec+(order_AmHigh.at(0).hour()-7);
            }
            else{
                double hourDec=(order_AmHigh.at(i).minute()+60-order_AmHigh.at(i-1).minute())/60.0;
                int hInt=order_AmHigh.at(i).hour()-order_AmHigh.at(i-1).hour()-1;
                hour=hInt+hourDec;
            }
            power_AmHigh+=hour*orderEnd;
            orderEnd=orderHash.value(order_AmHigh.at(i));
            if (i==order_AmHigh.count()-1){
                double hourDec=(60-order_AmHigh.at(i).minute())/60.0;
                hour=11-order_AmHigh.at(i).hour()-1+hourDec;
                power_AmHigh+=hour*orderEnd;
            }
        }
    }
    else{
         power_AmHigh+=4*orderEnd;
    }
/*!
 * 平段(11:00-19:00)
 */
    if (order_Normal.count()!=0){
        double hour;
        for (int i=0;i<order_Normal.count();++i){

            if (i==0){
                double hourDec=order_Normal.at(0).minute()/60.0;
                hour=hourDec+order_Normal.at(0).hour()-11;
            }
            else{
                double hourDec=(order_Normal.at(i).minute()+60-order_Normal.at(i-1).minute())/60.0;
                int hInt=order_Normal.at(i).hour()-order_Normal.at(i-1).hour()-1;
                hour=hInt+hourDec;
            }
            power_Normal+=hour*orderEnd;
            orderEnd=orderHash.value(order_Normal.at(i));
            if (i==order_Normal.count()-1){
                double hourDec=(60-order_Normal.at(i).minute())/60.0;
                hour=19-order_Normal.at(i).hour()-1+hourDec;
                power_Normal+=hour*orderEnd;
            }
        }
    }
    else{
         power_Normal+=8*orderEnd;
    }
/*!
 * 晚高段(19:00-23:00)
 */
    if (order_PmHigh.count()!=0){
        double hour;
        for (int i=0;i<order_PmHigh.count();++i){
            if (i==0){
                double hourDec=order_PmHigh.at(0).minute()/60.0;
                hour=hourDec+order_PmHigh.at(0).hour()-19;
            }
            else{
                double hourDec=(order_PmHigh.at(i).minute()+60-order_PmHigh.at(i-1).minute())/60.0;
                int hInt=order_PmHigh.at(i).hour()-order_PmHigh.at(i-1).hour()-1;
                hour=hInt+hourDec;
            }
            power_PmHigh+=hour*orderEnd;
            orderEnd=orderHash.value(order_PmHigh.at(i));
            if (i==order_PmHigh.count()-1){
                double hourDec=(60-order_PmHigh.at(i).minute())/60.0;
                hour=23-order_PmHigh.at(i).hour()-1+hourDec;
                power_PmHigh+=hour*orderEnd;
            }
        }
    }
    else{
         power_PmHigh+=4*orderEnd;
    }
/*!
 * 晚低段(23:00-24:00)
 */
    if (order_PmLow.count()!=0){
        double hour;
        for (int i=0;i<order_PmLow.count();++i){
            if (i==0){
                double hourDec=order_PmLow.at(0).minute()/60.0;
                hour=hourDec+order_PmLow.at(0).hour()-23;
            }
            else{
                double hourDec=(order_PmLow.at(i).minute()+60-order_PmLow.at(i-1).minute())/60.0;
                int hInt=order_PmLow.at(i).hour()-order_PmLow.at(i-1).hour()-1;
                hour=hInt+hourDec;
            }
            power_PmLow+=hour*orderEnd;
            orderEnd=orderHash.value(order_PmLow.at(i));
            if (i==order_PmLow.count()-1){
                double hourDec=(60-order_PmLow.at(i).minute())/60.0;
                hour=24-order_PmLow.at(i).hour()-1+hourDec;
                power_PmLow+=hour*orderEnd;
            }
        } 
    }
    else{
         power_PmLow+=1*orderEnd;
    }
/*************************************************************************/
    QString power_Low_string,power_AmHigh_string,power_Normal_string,power_PmHigh_string,power_Total_string;
    double power_Low=power_AmLow+power_PmLow;
    power_Total=power_Low+power_AmHigh+power_Normal+power_PmHigh;
    power_Low_string.setNum(power_Low,'f',5);
    power_AmHigh_string.setNum(power_AmHigh,'f',5);
    power_Normal_string.setNum(power_Normal,'f',5);
    power_PmHigh_string.setNum(power_PmHigh,'f',5);
    power_Total_string.setNum(power_Total,'f',5);
    textEdit->clear();
    textEdit->setFontPointSize(10);
    textEdit->setTextColor(Qt::black);
    textEdit->append(tr("Low period power")+"(00:00-07:00,23:00-24:00):");
    textEdit->setFontPointSize(12);
    textEdit->setTextColor(QColor("#FF1493"));
    textEdit->append(" "+power_Low_string+" MWH");
    textEdit->setFontPointSize(10);
    textEdit->setTextColor(Qt::black);
    textEdit->append(tr("AM high period power")+QString("(07:00-11:00):"));
    textEdit->setFontPointSize(12);
    textEdit->setTextColor(QColor("#B03060"));
    textEdit->append(" "+power_AmHigh_string+" MWH");
    textEdit->setFontPointSize(10);
    textEdit->setTextColor(Qt::black);
    textEdit->append(tr("Normal period power")+QString("(11:00-19:00):"));
    textEdit->setFontPointSize(12);
    textEdit->setTextColor(QColor("#458B00"));
    textEdit->append(" "+power_Normal_string+" MWH");
    textEdit->setFontPointSize(10);
    textEdit->setTextColor(Qt::black);
    textEdit->append(tr("PM high period power")+QString("(19:00-23:00):"));
    textEdit->setFontPointSize(12);
    textEdit->setTextColor(QColor("#0000FF"));
    textEdit->append(" "+power_PmHigh_string+" MWH");
    textEdit->setTextColor(Qt::black);
    textEdit->append("-----------------------------");
    textEdit->append(tr("Total dispatching power:"));
    textEdit->setTextColor(QColor("#FF0000"));
    textEdit->append(" "+power_Total_string+" MWH");
    return ;
}
void PowerWindow::clearAll(){
    tableModel->clear();
    tableModelInit();
}
void PowerWindow::setDatatime(){
    auto datetime=QDateTime::currentDateTime();
    QString datetimeString=datetime.date().toString("yyyy-MM-dd")+" "+datetime.time().toString("hh:mm:ss");
    datetimeLCD->display(datetimeString);
}

void PowerWindow::about(){
    QMessageBox::about(this,tr("About..."),QString("<center><h3>%1 v2.0\
</h3></center><center><font size='2'><em>%2</em></font></center><center><font size='2'>\
Copyright(c)2010-2016 HeJia All Rights Reserved.</font></center>License:<a href='http://www.gnu.org/licenses/gpl.html'>GPL V3</a>\
 %3%4 %5<br>%7<br><a href='http://git.oschina.net/hehuim/DispatchingPowerCalculator'>%6</a>\
 <font size='3'>E-mail: </font><a href='mailto:he_jia@outlook.com?subject=%8&body=%8'>\
he_jia@outlook.com</a><br><font size='3'><b>%9</b></font>").arg(tr("Dispatching Power Calculator"),\
                                                                tr("Originally Developed for SinoHydro"),\
                                                                tr("compiled on"),\
                                                                __TIME__,__DATE__,\
                                                                tr("project homepage"),\
                                                                tr("your suggestion will be highly appreciated:"),\
                                                                tr("suggestion"),\
                                                                tr("Open source software and without any warranty for the result.")));
}


